package com.hengpeng.itfints.controller.assign;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.hengpeng.common.exception.ServiceResult;
import com.hengpeng.common.persist.entity.AbstractEntity.BoolValue;
import com.hengpeng.common.util.DateTimeUtil;
import com.hengpeng.common.util.MoneyUtil;
import com.hengpeng.common.util.StringHelper;
import com.hengpeng.itfinbase.constants.RespCodeConstants;
import com.hengpeng.itfinbase.constants.TransCodeConstants;
import com.hengpeng.itfinbase.message.ResponseMessage;
import com.hengpeng.itfinbase.message.partner.CreditAssignRequest;
import com.hengpeng.itfinbase.message.partner.CreditAssignRequest.BidDetail;
import com.hengpeng.itfinbase.message.partner.CreditAssignRequest.BidDetail.BorrowerDetail;
import com.hengpeng.itfinbase.message.partner.CreditAssignRequest.DivDetail;
import com.hengpeng.itfinbase.message.partner.PartnerTransType;
import com.hengpeng.itfinbase.message.partner.QueryBalanceRequest;
import com.hengpeng.itfinbase.message.partner.QueryBalanceResponse;
import com.hengpeng.itfinbase.persist.BorrowInfo;
import com.hengpeng.itfinbase.persist.CreditAssign;
import com.hengpeng.itfinbase.persist.CreditAssign.AssignStatus;
import com.hengpeng.itfinbase.persist.InvestInfo;
import com.hengpeng.itfinbase.persist.RepaymentPlan;
import com.hengpeng.itfinbase.persist.UserInfo;
import com.hengpeng.itfints.config.ConfigUtil;
import com.hengpeng.itfints.constants.TSConstants;
import com.hengpeng.itfints.controller.BaseController;
import com.hengpeng.itfints.tools.PageUtil;
import com.hengpeng.itfints.vo.MemberSession;

/**
 * <pre>
 * 债权转让控制器
 * </pre>
 * @author weiyuan
 * @version 1.0, 2015年7月25日
 */
@Controller
@RequestMapping("/assign")
public class AssignController extends BaseController
{
	/**
	 * <pre>
	 * 展示债权转让产品信息
	 * </pre>
	 * @param map
	 * @param request
	 * @param curPage
	 * @return
	 */
	@RequestMapping(value = "/list")
	public String list(ModelMap map, HttpServletRequest request, String curPage)
	{
		int int_curPage = (!StringHelper.isEmpty(curPage) ? Integer.parseInt(curPage) : 1);
		AssignStatus[] status = new AssignStatus[] { AssignStatus.PUBLISHED, AssignStatus.ASSIGNING,
				AssignStatus.ASSIGNSUCCESS };
		ServiceResult<List<CreditAssign>> serviceResult = serviceFactory.getAssignService().queryList(status,
				int_curPage, 10);
		PageUtil pUtil = new PageUtil(10, serviceResult.getReturnListSize(), int_curPage);
		List<?> list = serviceFactory.getAssignService().queryDeal();
		Object[] o = new Object[] { 0, 0 };
		if (list != null && list.size() > 0)
		{
			o = (Object[]) list.get(0);
		}
		map.put("count", o[0]);
		map.put("money", o[1]);
		map.put("dataList", serviceResult.getReturnValue());
		map.put("PageUtil", pUtil);
		map.put("dataList", serviceResult.getReturnValue());
		map.put("PageUtil", pUtil);
		map.put("assign_fee", ConfigUtil.getParameter("ASSIGN_FEE"));// 转让手续费率
		map.put("assign_rate", ConfigUtil.getParameter("ASSIGN_RATE"));// 债权转让率
		return "/page/borrowInfo/assignlist.jsp";
	}

	/**
	 * <pre>
	 * 查看产品详细信息
	 * </pre>
	 * @param map
	 * @param request
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/detail")
	public String detail(ModelMap map, HttpServletRequest request, Long investInfoId, Long assignId)
	{
		InvestInfo invest = serviceFactory.getPersistService().get(InvestInfo.class, investInfoId);
		BorrowInfo borrowInfo = serviceFactory.getPersistService().get(BorrowInfo.class, invest.getBorrowInfoId());
		List<InvestInfo> resultInvestInfos = serviceFactory.getInvestInfoService().queryInvestList(borrowInfo.getId(),
				null, null);
		List<RepaymentPlan> resultRepaymentPlans = serviceFactory.getRepaymentService().getRepaymentPlans(null,
				borrowInfo.getId(), null, null);
		CreditAssign creditAssign = serviceFactory.getPersistService().get(CreditAssign.class, assignId);
		map.put("borrowInfo", borrowInfo);
		map.put("investList", resultInvestInfos);
		map.put("repaymentList", resultRepaymentPlans);
		map.put("creditAssign", creditAssign);
		return "/page/borrowInfo/assigndetail.jsp";
	}

	/**
	 * <pre>
	 * 投资人发布债权转让信息
	 * </pre>
	 * @param map
	 * @param request
	 * @param investInfoId
	 * @return
	 */
	@RequestMapping(value = "/createAssign")
	public String createAssign(ModelMap map, HttpServletRequest request, Long investInfoId)
	{
		CreditAssignRequest createAssignRequest = new CreditAssignRequest();
		createAssignRequest.setInvestInfoId(investInfoId);
		createAssignRequest.setTransType(TransCodeConstants.TradeTransCode.TRADE_CREATEASSIGEN);
		createAssignRequest.setAssign_duration(Integer.parseInt(ConfigUtil.getParameter("ASSIGN_DURATION")));
		serviceFactory.getProtFactory().remoteTrans(createAssignRequest);
		return "/assign/canAssignList.htm";
	}

	/**
	 * <pre>
	 * 承接债权
	 * </pre>
	 * @param map
	 * @param request
	 * @param investInfoId
	 * @return
	 */
	@RequestMapping(value = "/doAssign")
	@ResponseBody
	public ServiceResult<ResponseMessage> doAssign(ModelMap map, HttpServletRequest request, Long assignId)
	{
		ServiceResult<ResponseMessage> result = new ServiceResult<ResponseMessage>();
		ResponseMessage response = new ResponseMessage();
		MemberSession member = (MemberSession) request.getSession().getAttribute(TSConstants.CLIENT_SESSION_MEMBER);
		/** 获取债权实时信息 */
		CreditAssign creditAssign = serviceFactory.getAssignService().getCurrentAssignInfo(assignId);
		BorrowInfo borrowInfo = serviceFactory.getPersistService()
				.get(BorrowInfo.class, creditAssign.getBorrowInfoId());
		InvestInfo investInfo = serviceFactory.getPersistService()
				.get(InvestInfo.class, creditAssign.getInvestInfoId());
		/** 购买此债权的购买价格 */
		Double buyMoney = creditAssign.getSellMoney()
				* (1 - Double.parseDouble(ConfigUtil.getParameter("ASSIGN_RATE")));
		if (member == null)
		{
			result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			result.setMessage("请先登录");
			result.setReturnValue(response);
			return result;
		}
		if (member.getUser() == null)
		{
			result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			result.setMessage("当前用户信息异常,请重新登录");
			result.setReturnValue(response);
			return result;
		}
		if (member.getUser().getId().equals(creditAssign.getSellUserId()))
		{
			result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			result.setMessage("不允许购买自己转让的债权标的");
			result.setReturnValue(response);
			return result;
		}
		if (member.getUser().getIsInvestor() == BoolValue.NO)
		{
			result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			result.setMessage("对不起,您不是投资人角色");
			result.setReturnValue(response);
			return result;
		}
		try
		{
			/**
			 * 校验投资人可用余额是否够用
			 */
			QueryBalanceRequest queryBalanceRequest = new QueryBalanceRequest();
			queryBalanceRequest.setUsrCustId(member.getUser().getTrustAccountId());
			queryBalanceRequest.setUserId(member.getUser().getId());
			queryBalanceRequest.setPartnerTransType(PartnerTransType.QueryBalanceBg);
			queryBalanceRequest.setTransType(TransCodeConstants.PartnerTransCode.REQUEST);
			QueryBalanceResponse queryBalanceResponse = (QueryBalanceResponse) serviceFactory.getProtFactory()
					.remoteTrans(queryBalanceRequest);
			if (RespCodeConstants.CommonCode.TRANS_SUC.equals(queryBalanceResponse.getRespCode()))
			{
				if (buyMoney / 100 > (Double.parseDouble(queryBalanceResponse.getAvlBal().replaceAll(",", ""))))
				{
					result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
					result.setMessage("余额不足!");
					result.setReturnValue(response);
					return result;
				}
			}
			else
			{
				result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
				result.setMessage("承接失败,原因如下：" + queryBalanceResponse.getRespDesc());
				result.setReturnValue(response);
				return result;
			}
		}
		catch (Exception e)
		{
			result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			result.setMessage("承接失败,原因如下：余额查询失败!具体信息如下:" + e.getMessage());
			result.setReturnValue(response);
			return result;
		}
		/** 手续费 */
		Double fee = creditAssign.getSellMoney() * Double.parseDouble(ConfigUtil.getParameter("ASSIGN_FEE"));
		CreditAssignRequest reqMsg = new CreditAssignRequest();
		reqMsg.setLeftMoney(creditAssign.getLeftMoney());// 剩余本息
		reqMsg.setLeftPlanNum(creditAssign.getLeftPlanNum());// 剩余期数
		reqMsg.setRepaymentedMoney(creditAssign.getRepaymentedMoney());// 已还金额
		reqMsg.setSellCustId(creditAssign.getSellTrustAccountId());// 转让人客户号
		reqMsg.setCreditAmt(MoneyUtil.convertFenToYuan(creditAssign.getSellMoney()));// 债权转让的转让金额
		reqMsg.setCreditDealAmt(MoneyUtil.convertFenToYuan(buyMoney.longValue()));// 承接金额
		reqMsg.setFee(MoneyUtil.convertFenToYuan(fee.longValue()));// 扣款手续费,手续费在承接金额中扣除,出让人实际收入= 承接金额 - 手续费
		reqMsg.setBuyCustId(member.getUser().getTrustAccountId());// 承接人客户号
		reqMsg.setBuyUserId(member.getUser().getId().toString());// 承接人id
		reqMsg.setOrdId(String.valueOf(assignId));// 订单号
		reqMsg.setOrdDate(DateTimeUtil.formatToStr(new Date(), DateTimeUtil.DATE_FORMAT_YYYYMMDD));// 订单日期

		List<BorrowerDetail> listBorrowerDetail = new ArrayList<BorrowerDetail>();
		BorrowerDetail borrowerDetail = new CreditAssignRequest().new BidDetail().new BorrowerDetail();
		borrowerDetail.setBorrowerCustId(borrowInfo.getBorrowUserTrustAccountId());
		borrowerDetail.setBorrowerCreditAmt(MoneyUtil.convertFenToYuan(creditAssign.getSellMoney()));
		borrowerDetail.setPrinAmt(MoneyUtil.convertFenToYuan(creditAssign.getRepaymentedMoney()));// 已还金额
		borrowerDetail.setProId(borrowInfo.getId().toString());
		listBorrowerDetail.add(borrowerDetail);

		Map<String, List<BidDetail>> mapBidDetails = new HashMap<String, List<BidDetail>>();
		List<BidDetail> listBidDetail = new ArrayList<BidDetail>();
		BidDetail bidDetail = new CreditAssignRequest().new BidDetail();
		bidDetail.setBidOrdId(investInfo.getId().toString());
		bidDetail
				.setBidOrdDate(DateTimeUtil.formatToStr(investInfo.getInvestTime(), DateTimeUtil.DATE_FORMAT_YYYYMMDD));
		bidDetail.setBidCreditAmt(MoneyUtil.convertFenToYuan(creditAssign.getSellMoney()));// BidDetails中的转让金额总和等于CreditAmt
		bidDetail.setBorrowerDetails(listBorrowerDetail);
		listBidDetail.add(bidDetail);
		mapBidDetails.put("BidDetails", listBidDetail);
		reqMsg.setBidDetails(mapBidDetails);

		List<DivDetail> listDivDetails = new ArrayList<DivDetail>();
		DivDetail divDetail = new CreditAssignRequest().new DivDetail();
		divDetail.setDivAcctId("MDT000001");// 固定平台主账户
		divDetail.setDivAmt(MoneyUtil.convertFenToYuan(fee.longValue()));
		listDivDetails.add(divDetail);
		reqMsg.setDivDetails(listDivDetails);

		reqMsg.setPartnerTransType(PartnerTransType.CreditAssign);
		reqMsg.setTransType(TransCodeConstants.PartnerTransCode.REQUEST);
		response = (ResponseMessage) serviceFactory.getProtFactory().remoteTrans(reqMsg);

		result.setCode(RespCodeConstants.CommonCode.TRANS_SUC);
		result.setMessage(RespCodeConstants.CommonCode.TRANS_SUC_MSG);
		result.setReturnValue(response);
		return result;
	}

	/**
	 * <pre>
	 * 投资人可转让的债权列表
	 * </pre>
	 * @param map
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/canAssignList")
	public String canAssignList(ModelMap map, HttpServletRequest request)
	{
		UserInfo m = getSessionMember(request).getUser();
		List<CreditAssign> dataList = serviceFactory.getAssignService().queryCanCreditAssignList(m.getId());
		map.put("canAssignList", dataList);
		map.put("assign_fee", ConfigUtil.getParameter("ASSIGN_FEE"));// 转让手续费率
		map.put("assign_rate", ConfigUtil.getParameter("ASSIGN_RATE"));// 折价率
		return "/page/account/investlog/canAssignList.jsp";
	}

	/**
	 * <pre>
	 * 转让中的债权
	 * </pre>
	 * @param map
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/assigningList")
	public String assigningList(ModelMap map, HttpServletRequest request)
	{
		UserInfo m = getSessionMember(request).getUser();
		List<CreditAssign> dataList = serviceFactory.getAssignService().queryAssigningList(m.getId());
		map.put("assigningList", dataList);
		map.put("assign_fee", ConfigUtil.getParameter("ASSIGN_FEE"));// 转让手续费率
		map.put("assign_rate", ConfigUtil.getParameter("ASSIGN_RATE"));// 债权转让率
		return "/page/account/investlog/assigningList.jsp";
	}

	/**
	 * <pre>
	 * 已转让的债权
	 * </pre>
	 * @param map
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/assignedList")
	public String assignedList(ModelMap map, HttpServletRequest request)
	{
		UserInfo m = getSessionMember(request).getUser();
		List<CreditAssign> dataList = (List<CreditAssign>) serviceFactory.getAssignService().queryAssignedList(
				m.getId());
		map.put("assignedList", dataList);
		map.put("assign_fee", ConfigUtil.getParameter("ASSIGN_FEE"));// 转让手续费率
		map.put("assign_rate", ConfigUtil.getParameter("ASSIGN_RATE"));// 债权转让率
		return "/page/account/investlog/assignedList.jsp";
	}

	/**
	 * <pre>
	 * 已购买的债权
	 * </pre>
	 * @param map
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/buyedList")
	public String buyedList(ModelMap map, HttpServletRequest request)
	{
		UserInfo m = getSessionMember(request).getUser();
		List<CreditAssign> dataList = serviceFactory.getAssignService().queryBuyedList(m.getId());
		map.put("buyedList", dataList);
		map.put("assign_fee", ConfigUtil.getParameter("ASSIGN_FEE"));// 转让手续费率
		map.put("assign_rate", ConfigUtil.getParameter("ASSIGN_RATE"));// 债权转让率
		return "/page/account/investlog/buyedList.jsp";
	}

}
